#include "queue.h"  
#include "threadpool.h"  
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "cJSON.h"
#include <signal.h>
#include <unistd.h>



int flag = 1;

// 信号处理函数
void fun(int sig) {
    flag = 0;
    printf("关闭成功\n");
}

int sock = 0;



// 生产者线程
void *fun1(void *arg) {
    THP *p = (THP *)arg;
    DAT data;
    

    int ret = 0;
    char buf[1024] = {0};

    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
	sock = socket(AF_INET, SOCK_DGRAM, 0);
	if (sock == -1) 
	{
		perror("socket");
        	exit(-1);
	}
    addr.sin_family = AF_INET;
    addr.sin_port = htons(6666);
    addr.sin_addr.s_addr = inet_addr("192.168.198.128");

    ret = bind(sock, (struct sockaddr *)&addr, sizeof(struct sockaddr));
    if (ret == -1) {
        perror("bind");
        exit(-1);
    }

    int len = sizeof(struct sockaddr);
    cJSON *json = NULL;

    while (flag == 1) {
        ret = recvfrom(sock, buf, 1024, 0, (struct sockaddr *)&data.cliaddr, &len);
        if (ret == -1) {
            perror("recvfrom");
            exit(-1);
        }
	printf("shengchanzhe_sock:%d\n",sock);
        puts(buf);

        json = cJSON_Parse(buf);

        cJSON *node = NULL;

        // 解析 JSON 数据
        node = cJSON_GetObjectItem(json, "type");
        if (node == NULL) {
            printf("找不到 'type'\n");
            cJSON_Delete(json);
            continue;
        }
        if (node->type == cJSON_Number) {
            data.type = node->valueint;
        }

        node = cJSON_GetObjectItem(json, "count");
        if (node == NULL) {
            printf("找不到 'count'\n");
            cJSON_Delete(json);
            continue;
        }
        if (node->type == cJSON_String) {
            strcpy(data.count, node->valuestring);
        }

        node = cJSON_GetObjectItem(json, "num1");
        if (node == NULL) {
            printf("找不到 'num1'\n");
            cJSON_Delete(json);
            continue;
        }
        if (node->type == cJSON_Number) {
            data.num1 = node->valuedouble;
        }

        node = cJSON_GetObjectItem(json, "num2");
        if (node == NULL) {
            printf("找不到 'num2'\n");
            cJSON_Delete(json);
            continue;
        }
        if (node->type == cJSON_Number) {
            data.num2 = node->valuedouble;
        }
	

        sem_wait(&p->semw);
        pthread_mutex_lock(&p->mutex);
        push(data, p->que);
        pthread_mutex_unlock(&p->mutex);
        sem_post(&p->semr);

        
    }
	printf("入队: %f %f\n", p->que->data.num1, p->que->data.num2);
    cJSON_Delete(json);
    close(sock);
    printf("生产者结束\n");
}

// 消费者线程
void *fun2(void *arg) {
    THP *p = (THP *)arg;
    DAT dat;
    int ret = 0;
    char *dest = NULL;
    struct number num;
    memset(&num,0,sizeof(num));
    cJSON *json = NULL;
    while (flag == 1) {
	printf("%ld ", pthread_self() % 100);

        sem_wait(&p->semr);
        pthread_mutex_lock(&p->mutex);
        dat = front(p->que);
	sem_post(&p->semw);
        pthread_mutex_unlock(&p->mutex);
		if(dat.type == 1)
		{
		num.sum = dat.num1 + dat.num2;
		printf("num.sum:%f\n",num.sum);
		}

		else if(dat.type == 2)
		{
		num.sum = dat.num1 - dat.num2;
		printf("num.sum:%f\n",num.sum);
		}

		else if(dat.type == 3)
		{
		num.sum = dat.num1 * dat.num2;
		printf("num.sum:%f\n",num.sum);
		}
		else if(dat.type == 4)
		{
		num.sum = dat.num1 / dat.num2;
		printf("num.sum:%f\n",num.sum);
		}
      
	json = cJSON_CreateObject();

	cJSON_AddItemToObject(json,"sum",cJSON_CreateNumber(num.sum));	
	
	dest = cJSON_Print(json);
	puts(dest);
	

	ret = sendto(sock,dest,strlen(dest),0,(struct sockaddr *)&dat.cliaddr,sizeof(struct sockaddr));
		if(ret == -1)
		{
			perror("sendto");
		}
        pop(p->que);
        sleep(1);
    }

    printf("消费者 %ld 结束\n", pthread_self() % 100);
}

int main() {
    int threads = 5;
    int queue_length = 5;

    // 创建线程池
    THP *p = create_threadpool(threads, queue_length, fun2);

    // 创建生产者
    pthread_t tid1 = 0;
    int ret = pthread_create(&tid1, NULL, fun1, p);
    if (ret != 0) {
        perror("pthread_create");
        exit(-1);
    }

    // 设置 SIGINT 信号处理函数
    signal(SIGINT, fun);

    // 主循环
    while (1) {
        printf("%d", flag);
        if (flag == 0) {
            break;
        }
        sleep(1);
    }

    // 等待所有线程完成
    destroy_threadpool(p);

    // 检查队列是否为空
    if (isempty(p->que) != 0) {
        delLinkMem(p->que);
    }
    printf("队列为空\n");

    // 等待生产者线程完成
    pthread_join(tid1, NULL);

    return 0;
}
